#include <Uefi.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/SimplePointer.h>

EFI_STATUS
TestMouseSimple()
{
  EFI_STATUS Status                  = EFI_SUCCESS;
  EFI_SIMPLE_POINTER_PROTOCOL *Mouse = NULL;
  EFI_SIMPLE_POINTER_STATE State     = { 0 };
  EFI_EVENT Events[2]                = { NULL };

  gST->ConOut->EnableCursor(gST->ConOut, TRUE);

  do {

    Status = gBS->LocateProtocol(&gEfiSimplePointerProtocolGuid, NULL, &Mouse);
    if (EFI_ERROR(Status)) {

      Print(L"gBS->LocateProtocol Error: %d\n", Status);
      break;
    }

    Status = Mouse->Reset(Mouse, TRUE);
    if (EFI_ERROR(Status)) {

      Print(L"Mouse->Reset Error: %d\n", Status);
      break;
    }

    Events[0] = Mouse->WaitForInput;
    Events[1] = gST->ConIn->WaitForKey;

    while (1) {

      EFI_INPUT_KEY Key = { 0 };
      UINTN Index       = 0;

      gBS->WaitForEvent(2, Events, &Index);
      if (Index == 0) {

        Mouse->GetState(Mouse, &State);
        Print(L"X:%d Y:%d Z:%d L:%d R:%d\n", State.RelativeMovementX, State.RelativeMovementY, State.RelativeMovementZ, State.LeftButton, State.RightButton);
      } else {

        gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
        if (Key.UnicodeChar == 'q') {

          break;
        }
      }
    }

  } while (0);

  return Status;
}

EFI_STATUS
UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
  return TestMouseSimple();
}
